package model;

import protocol.JT808_2019.*;
import utils.ExceptionUtils;
import utils.HexUtils;
import utils.StringUtils;
import java.util.List;

/**
 * JT/T 905.2 - 2014
 */
public class Protocol808_2019Model extends IModel {

    private final static int Protocol_Analysis = 0;//数据内容解析
    private final static int Protocol_Check = 1;//数据校验

    @Override
    protected void initTypes(List<String> list) {
        list.add(Protocol_Analysis,"数据内容解析");
        list.add(Protocol_Check,"数据校验");
    }

    @Override
    public String change(String input) {
        try{
            input = StringUtils.formatProtocol(input);

            byte[] list = HexUtils.toHexBytes(input);
            JT808_2019Cmd cmd = new JT808_2019Cmd(list);

            if (getType() == Protocol_Check){
                return checkProtocolStr(cmd,list);
            }

            byte order = cmd.order();

            switch (order) {
                case 0x00:
                    return new Handle808_2019JT00().handle(cmd);
                case 0x01:
                    return new Handle808_2019JT01().handle(cmd);
                case 0x02:
                    return new Handle808_2019JT02().handle(cmd);
                case 0x05:
                    return new Handle808_2019JT05().handle(cmd);
                case 0x06:
                    return new Handle808_2019JT06().handle(cmd);
                case 0x07:
                    return new Handle808_2019JT07().handle(cmd);
                case 0x08:
                    return new Handle808_2019JT08().handle(cmd);
                case 0x09:
                    return new Handle808_2019JT09().handle(cmd);
                case (byte) 0x10:
                    return new Handle808_2019JT10().handle(cmd);
                case (byte) 0x80:
                    return new Handle808_2019JT80().handle(cmd);
                case (byte) 0x81:
                    return new Handle808_2019JT81().handle(cmd);
                case (byte) 0x82:
                    return new Handle808_2019JT82().handle(cmd);
                case (byte) 0x83:
                    return new Handle808_2019JT83().handle(cmd);
                case (byte) 0x84:
                    return new Handle808_2019JT84().handle(cmd);
                case (byte) 0x85:
                    return new Handle808_2019JT85().handle(cmd);
                case (byte) 0x86:
                    return new Handle808_2019JT86().handle(cmd);
                case (byte) 0x87:
                    return new Handle808_2019JT87().handle(cmd);
                case (byte) 0x88:
                    return new Handle808_2019JT88().handle(cmd);
                case (byte) 0x89:
                    return new Handle808_2019JT89().handle(cmd);
                case (byte) 0x8A:
                    return new Handle808_2019JT8A().handle(cmd);

                default:
                    return "未匹配的命令字" + (cmd.readOrder());
            }

        }catch (Exception e){
            return "数据校验失败\n"+ ExceptionUtils.getExceptionMsg(e);
        }
    }

    private String checkProtocolStr(JT808_2019Cmd cmd, byte[] data) {
        StringBuilder builder = new StringBuilder();

        if (data[0] != 0x7e){
            builder.append("数据包头错误(正常包头：7e)："+HexUtils.toHexStr(new byte[]{data[0],data[1]}));
            builder.append("\r\n");
            return builder.toString();
        }

        if (data[data.length - 1] != 0x7e){
            builder.append("数据包尾错误(正常包尾：7e)："+HexUtils.toHex(data[data.length - 1],1));
            builder.append("\r\n");
            return builder.toString();
        }

        builder.append("命令字："+cmd.readOrder());
        builder.append("\r\n");

        int attr = HexUtils.toInt(data,3,2);

        builder.append("消息体属性："+HexUtils.toHex(data[3],1)+" "+HexUtils.toHex(data[4],1)+"("+HexUtils.convertToBinary(attr,2)+")");
        builder.append("\r\n");

        builder.append("    保留："+((attr >> 15)&0x01));
        builder.append("\r\n");
        builder.append("    版本标识："+((attr >> 14)&0x01));
        builder.append("\r\n");
        builder.append("    分包(为1时加密)："+((attr >> 13)&0x01));
        builder.append("\r\n");
        builder.append("    数据加密方式（3位均为0则不加密）："+((attr >> 12)&0x01)+((attr >> 11)&0x01)+((attr >> 10)&0x01));
        builder.append("\r\n");

        int len = attr&0x3FF;//只取低10位
        builder.append("    消息体长度："+len);
        builder.append("\r\n");

        builder.append("协议版本号："+HexUtils.toHex(data[5],1));
        builder.append("\r\n");

        builder.append("通讯号："+HexUtils.toHexStr(data,6,10));
        builder.append("\r\n");

        String seq = HexUtils.toHexStr(data,16,2);

        builder.append("流水号："+seq+"("+Integer.parseInt(seq.replaceAll(" ",""),16)+")");
        builder.append("\r\n");

        builder.append("数据区："+cmd.readBCD(cmd.leftSize()));
        builder.append("\r\n");

        return builder.toString();
    }

}
